package msgo

import (
	"errors"
	"fmt"
	"gitee.com/MrDaiM/msgo/mserror"
	"net/http"
	"runtime"
	"strings"
)

func detailMsg(err any) string {
	var pcs [32]uintptr // 传出参数

	n := runtime.Callers(3, pcs[:]) // 先跳过前三层的函数 ctx.Logger.Error(detailMsg(err))， defer func() ，func(ctx *Context)
	// n 对应总共多少个栈
	var sb strings.Builder
	sb.WriteString(fmt.Sprintf("%v\n", err))
	for _, pc := range pcs[0:n] {
		fn := runtime.FuncForPC(pc)
		file, line := fn.FileLine(pc) // 返回文件名和 行数
		sb.WriteString(fmt.Sprintf("\n\t%s:%d", file, line))

	}
	return sb.String()
}

func Recovery(next HandlerFunc) HandlerFunc {
	return func(ctx *Context) {
		defer func() {
			if err := recover(); err != nil {
				if err2 := err.(error); err2 != nil {
					var msError *mserror.MsError
					if errors.As(err2.(error), &msError) {
						msError.ExecResult()
						return
					}
				}

				ctx.Logger.Error(detailMsg(err))
				ctx.Fail(http.StatusInternalServerError, "Internal Server Error") //服务器错误信息
			}
		}()

		next(ctx)

	}
}
